<template>
  <div class="lyric-wrap">
    <!-- {{lyric}} -->
    <div v-for="(item, index) in lyricArr" ref="" :key="index" class="lyric-item" @click="playThisLyric(item.time)">
      <span class="lyric-text"  :class="{ isActive: index === lyricIndex }">{{item.lyric}}</span>
      <span class="lyric-time">
        {{item.time}}
      </span>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import { getLyric } from '@/api/song.js'

export default {
  data () {
    return {
      lyricArr: [],
      lyricIndex: 0 // 在唱的那行歌词
    }
  },
  computed: {
    ...mapState([
      'curSong'
    ])
  },
  watch: {
    // 监听歌曲变化
    'curSong.songInfo.id': {
      immediate: true,
      handler () {
        this.showLyric()
      }
    },
    'curSong.curTime': {
      handler (newVal) {
        // 找出第一个大于当前播放时间的行,减一就是当前行
        this.lyricIndex = this.lyricArr.findIndex(item => {
          return this.timeFormat(item.time) >= newVal
        }) - 1 // 减1是因为找的是当前播放的下一行
      }
    },
    lyricIndex: {
      handler () {
        this.scrollLyric()
      }
    }
  },
  methods: {
    // 展示歌词
    async showLyric () {
      if (Object.keys(this.curSong.songInfo).length === 0) return
      const res = await getLyric(this.curSong.songInfo.id)
      if (res.data.code !== 200) {
        return this.$message.error('获取歌词失败')
      }
      console.log(res)
      this.lyricArr = [] // 先清空,不然词都叠一起了
      this.cutLyric(res.data.lrc.lyric)
    },
    // 分割歌词数据
    cutLyric (lyric) {
      const a = lyric.split('\n') // a是[11:11.11]...歌词的形式,用slice截取字符串,这里最后会有个空元素,感觉无伤大雅
      a.forEach(item => {
        const temp = {}
        const splitArr = item.split(']') // 分完后['[03:13.333', 'b']
        temp.time = splitArr[0].slice(1) // 截取一下,格式变成03:13.333
        temp.lyric = splitArr[1]
        this.lyricArr.push({ ...temp }) // 注意这里的传址问题,那个力扣题的教训,对象有多层时也无法深拷贝
      })
      // 歌词播到最后一句不会isActive,冷门歌有些只有歌词,没有[00:00.222]时间,这样子处理会有错

      // 把最后一个元素(因为最后一个歌词后面的\n分割出的东西,元素都为空)的时间设为总时长
      const totalT = this.curSong.totalTime / 1000 // 化成xx秒.xxx
      let min = parseInt(totalT / 60) // 算出分钟
      const second = totalT - min * 60 // 得出秒数
      // const hour = parseInt(min / 60) // 算出小时,一般有小时这么长的歌,歌词格式应该跟我现在处理的不一样
      if (min < 10) {
        min = '0' + min.toString() // 不够两位,前面补0
      } else {
        min = min.toString()
      }
      const str = min + ':' + second.toString()
      this.lyricArr[this.lyricArr.length - 1].time = str
    },
    // 时间转换
    timeFormat (time) {
      // 转换时间,从'10:2.141'转成秒.xxx
      const timeArr = time.split(':') // ['01', '4.111'], 注意后面的秒数也有可能没到小数后三位,可能是两位
      for (let i = 0; i < timeArr.length; i++) {
        timeArr[i] = parseFloat(timeArr[i])
      }
      // 转换后的时间
      const timeSecond = timeArr.reduce(function format (preVal, newVal) {
        return preVal * 60 + newVal
      }, 0)
      return timeSecond
    },
    // 播放该句歌词
    playThisLyric (time) {
      this.$emit('playLyric', this.timeFormat(time)) // 传给父组件
    },
    // 歌词滚动
    scrollLyric () {
      const curRow = document.getElementsByClassName('isActive')[0].parentNode // 歌词文本父节点
      // const lyricContainer = document.getElementsByClassName('lyric-wrap')[0].parentNode
      // console.log(lyricContainer)
      if (curRow.offsetTop > 377) {
        // scroll要滚动,每次加25,刚好是一行歌词高度
        // lyricContainer.scrollTop += 25
        curRow.scrollIntoView({ block: 'center', behavior: 'smooth' }) // 文档说自动滚父级来使元素可见,可这里是爷爷级了
      }
      // console.log(this.$refs.lyricContainer)  // undefined
      // console.log('client' + target[0].parentNode.clientTop)
      // console.log('target' + target[0].parentNode.offsetTop)
      // console.log('scroll' + target[0].parentNode.scrollTop) // 只有scrollTop可以修改,clientTop,offsetTop都是只读
    }
  }
}
</script>

<style lang="less" scoped>
.lyric-wrap {
  white-space: pre-line;
}
.lyric-item {
  color: #b4afaf;
  cursor: pointer;
  position: relative;
  height: 25px;
  line-height: 25px;
  &:hover {
    background: linear-gradient(to right, #fff, #eee);
  }
  &:hover .lyric-text{
    font-weight: bold;
  }

  .lyric-time {
    display: none;
  }
  // 利用hover控制别的元素显示
  &:hover .lyric-time{
    display: inline-block;
    position: absolute;
    bottom: 0;
    right: 10px;
  }
}
.isActive {
  color: #000;
  font-weight: bold;
}
</style>
